﻿namespace DriveJoy
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Net;
    using System.Runtime.Serialization.Json;
    using System.Windows;
    using Microsoft.Phone.Controls;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.IO.IsolatedStorage;
    using System.IO;
    using Microsoft.Phone.Shell;
    using Microsoft.Phone.Tasks;
    using System.Windows.Resources;
    using System.Linq;
    using DriveJoy.Models;

    /// <summary>
    /// Used to indicate what data is being returned by a particular HTTP request
    /// </summary>
    public enum Results { UserInfo, AlbumInfo, FolderInfo, ItemStructure, SkyDriveDownload, SkyDriveUpload,SkyDriveDelete,SkyDriveMove,SkyDriveCreateFolder,SkyDriveCreateAlbum };
    public enum CurrentDrive { Local,SkyDrive };

    /// <summary>
    /// The main landing page.
    /// </summary>
    public partial class MainPage : PhoneApplicationPage
    {
        public CurrentDrive currentDrive;
        public IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
        public string titleProgram = "DriveJoy({0}) - Connect your storage";
        public string localFileName = "AppSetting/LocalItemStructures.xml";
        public string skyDriveFileName = "AppSetting/SkyDriveItemStructures.xml";
        public string rootLocalDir = "";
        public string currLocalDir = "";
        public string currSkyDriveDir;
        public string parentCurrSkyDriveDir;
        public ItemStructure currSkyDriveItem;
        public ItemStructure currLocalItem;
        public List<ItemStructure> listSkyDriveItem;
        public List<ItemStructure> listLocalItem;
        #region skydrive signin
        /// <summary>
        /// The URI for the OAuth service's Authorize endpoint.
        /// </summary>
        private static readonly string OAuthAuthorizeUri = "https://oauth.live.com/authorize";

        /// <summary>
        /// The URI for the API service endpoint.
        /// </summary>
        private static readonly string ApiServiceUri = "https://apis.live.net/v5.0/";

        /// <summary>
        /// The applications client ID.
        /// </summary>
        private static readonly string ClientId = "000000004C0C211D"
            /* insert client ID here - go to http://manage.dev.live.com to get one */ ;

        /// <summary>
        /// The applications redirect URI (does not need to exist).
        /// </summary>
        private static readonly string RedirectUri = "https://oauth.live.com/desktop";

        /// <summary>
        /// Holds the retrieved access token.
        /// </summary>
        private string skyDriveAccessToken=string.Empty;

        /// <summary>
        /// The list of scopes.
        /// </summary>
        private string[] scopes = new string[] { "wl.basic", "wl.photos", "wl.skydrive" };

        /// <summary>
        /// The resource to request.
        /// </summary>
        private string user = "me";
        private string albums = "me/albums";
        private string folders = "me/skydrive/files";
        private string rootSkyDrive = "me/skydrive";
        public static string skydriveFormat = "{0}/files";

        private void GetSkyDriveUserData()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            WebClient client = new WebClient();
            client.OpenReadCompleted += this.OnClientOpenReadComplete;
            client.OpenReadAsync(this.BuildApiUri(this.user, Results.UserInfo), Results.UserInfo);

        }
        private void GetSkyDriveUserDataComplete(UserInfo info)
        {
            string output = String.Format(
                "DriveJoy({0})- Welcome {1} {2}","Skydrive",
                info.FirstName,
                info.LastName
                );
            this.loadingGrid.Visibility = Visibility.Collapsed;
            this.txtTitle.Text = output;
        }
        private void GetSkyDriveAlbumData()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            WebClient client = new WebClient();
            client.OpenReadCompleted += this.OnClientOpenReadComplete;
            client.OpenReadAsync(this.BuildApiUri(this.albums, Results.AlbumInfo), Results.AlbumInfo);
        }
        private void GetSkyDriveAlbumDataComplete(Albums albumList)
        {
            this.loadingGrid.Visibility = Visibility.Collapsed;
            foreach (AlbumInfo info in albumList.data)
            {
                string s = (info.Count == 1 ? String.Empty : "s");
            }
        }
        private void GetSkyDriveItem(string folderId)
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            WebClient client = new WebClient();
            client.OpenReadCompleted += this.OnClientOpenReadComplete;
            client.OpenReadAsync(this.BuildApiUri(folderId, Results.ItemStructure), Results.ItemStructure);
        }
        private void SyncSkyDriveItem(string accessToken, string folderId)
        {
            if (string.IsNullOrEmpty(accessToken)) //login to access into skydrive
            {
                this.LaunchOAuthFlow();
            }
            else //get current skydrive folder
            {
                GetSkyDriveItem(folderId);
            }
        }
        private void SaveItem(string fileName,IsolatedStorageFile isoStore,List<ItemStructure> listItem)
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            XmlUtils.SaveXML(fileName, isoStore, listItem);
            SaveItemComplete();
        }
        private void SaveItemComplete()
        {
            this.loadingGrid.Visibility = Visibility.Collapsed;
        }
        private void GetSkyDriveItemComplete(string folderID,ItemStructures itemStructureList, List<ItemStructure> listSkyDrive)
        {
            // add skydrive item to list of skydrive item
            foreach (ItemStructure f in itemStructureList.data)
            {
                int currTotal = listSkyDriveItem.Count;
                bool found = false;
                for (int i = 0; (!found) && i < currTotal; i++)
                {
                    if (listSkyDrive[i].Id == f.Id)
                    {
                        listSkyDrive.Remove(listSkyDrive[i]);
                        found = true;
                    }
                }
                // add item 
                f.ParentID = folderID;
                if (f.Type == ItemType.Album || f.Type == ItemType.Folder)
                {
                   
                    f.Image = "Image/doc-icon.png";
                }
                listSkyDrive.Add(f);
            }
            SaveItem(skyDriveFileName,isoStore,listSkyDriveItem);
            DisplaySkyDriveItem(folderID, listSkyDrive, this.listFile);
            this.txtTitle.Text = string.Format(titleProgram, "SkyDirve");
            this.loadingGrid.Visibility = Visibility.Collapsed;
            this.btnLocal.Visibility = Visibility.Visible;
            this.btnSkyDrive.Visibility = Visibility.Collapsed;
            currentDrive = CurrentDrive.SkyDrive;
        }
        private void DisplaySkyDriveItem(string folderId,List<ItemStructure> listSkyDrive,ListBox listView)
        {
            //SyncSkyDriveItem(this.skyDriveAccessToken, folderId); //auto sync

            List<ItemStructure> listItem = new List<ItemStructure>();
            foreach (ItemStructure i in listSkyDrive)
            {
                if (i.ParentID == folderId) listItem.Add(i);
            }
            if (currSkyDriveDir != parentCurrSkyDriveDir)
            {
                ItemStructure item = new ItemStructure();
                item.Id = parentCurrSkyDriveDir;
                item.Name = "..";
                item.Type = ItemType.Up;
                listItem.Insert(0, item);
            }
            listView.ItemsSource = listItem;
        }

        private void DownloadSkyDriveItem()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            WebClient client = new WebClient();
            client.OpenReadCompleted += this.OnClientOpenReadComplete;
            client.OpenReadAsync(this.BuildApiUri(currSkyDriveItem.Id, Results.SkyDriveDownload), Results.SkyDriveDownload);
        }
        private void DownloadSkyDriveItemComplete()
        {
            this.loadingGrid.Visibility = Visibility.Collapsed;
            GetLocalItem(Path.Combine(currLocalDir,"*"), isoStore);
        }
        private void UploadSkyDriveItem()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            try
            {
                IsolatedStorageFileStream stream = new IsolatedStorageFileStream(currLocalItem.Id, FileMode.Open, isoStore);
                Uri uploadUri = this.BuildApiUri(currLocalItem.Name, Results.SkyDriveUpload);
                const int BLOCK_SIZE = 4096;
                WebClient client = new WebClient();
                client.AllowReadStreamBuffering = true;
                client.AllowWriteStreamBuffering = true;
 
                // what to do when write stream is open
                client.OpenWriteCompleted += (s, args) =>
                {
                    using (BinaryReader br = new BinaryReader(stream))
                    {
                        using (BinaryWriter bw = new BinaryWriter(args.Result))
                        {
                            long bCount = 0;
                            long fileSize = stream.Length;
                            byte[] bytes = new byte[BLOCK_SIZE];
                            do
                            {
                                bytes = br.ReadBytes(BLOCK_SIZE);
                                bCount += bytes.Length;
                                bw.Write(bytes);
                            } while (bCount < fileSize);
                        }
                    }
                };
 
                // what to do when writing is complete
                client.WriteStreamClosed += (s, args) =>
                {
                    UploadSkyDriveItemComplete();
                };
 
                // Write to the WebClient
                client.OpenWriteAsync(uploadUri, "PUT");
            }
            catch (Exception e)
            {
                this.loadingGrid.Visibility = Visibility.Collapsed;
                MessageBox.Show(e.Message);
            }
        }
        private void UploadSkyDriveItemComplete()
        {
            this.loadingGrid.Visibility = Visibility.Collapsed;
            this.GetSkyDriveItem(currSkyDriveDir);
        }
        private void DeleteSkyDriveItem()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            WebClient client = new WebClient();
            client.UploadStringCompleted += this.OnClientUploadStringComplete;
            client.UploadStringAsync(this.BuildApiUri(currSkyDriveItem.Id, Results.SkyDriveDelete), "DELETE", "", Results.SkyDriveDelete);
        }
        private void DeleteSkyDriveItemComplete()
        {
            this.loadingGrid.Visibility = Visibility.Collapsed;
            if (currSkyDriveItem.Type != ItemType.File)
            {
                this.currSkyDriveDir = this.parentCurrSkyDriveDir;
            }
            this.GetSkyDriveItem(currSkyDriveDir);
        }
        private void GetSkyDriveFolderData()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            WebClient client = new WebClient();
            client.OpenReadCompleted += this.OnClientOpenReadComplete;
            client.OpenReadAsync(this.BuildApiUri(this.folders, Results.FolderInfo), Results.FolderInfo);
        }
        private void GetSkyDriveFolderDataComplete(Folders folderList)
        {
            this.loadingGrid.Visibility = Visibility.Collapsed;
            listFile.ItemsSource = folderList.data;
        }
        private void OnClientOpenReadComplete(object sender, OpenReadCompletedEventArgs e)
        {
            DataContractJsonSerializer deserializer;
            //skydrive user data
            if (e.UserState.Equals(Results.UserInfo))
            {
                deserializer = new DataContractJsonSerializer(typeof(UserInfo));
                UserInfo userInfo = (UserInfo)deserializer.ReadObject(e.Result);
                this.GetSkyDriveUserDataComplete(userInfo);
                this.GetSkyDriveItem(currSkyDriveDir);
            }
            else if (e.UserState.Equals(Results.AlbumInfo))
            {
                deserializer = new DataContractJsonSerializer(typeof(Albums));
                Albums albumInfo = (Albums)deserializer.ReadObject(e.Result);
                this.GetSkyDriveAlbumDataComplete(albumInfo);
            }
            else if (e.UserState.Equals(Results.FolderInfo))
            {
                deserializer = new DataContractJsonSerializer(typeof(Folders));
                Folders folderInfo = (Folders)deserializer.ReadObject(e.Result);
                this.GetSkyDriveFolderDataComplete(folderInfo);
            }//skydrive data
            else if (e.UserState.Equals(Results.ItemStructure))
            {
                deserializer = new DataContractJsonSerializer(typeof(ItemStructures));
                ItemStructures itemStructure = (ItemStructures)deserializer.ReadObject(e.Result);
                this.GetSkyDriveItemComplete(this.currSkyDriveDir, itemStructure,this.listSkyDriveItem);
            }
            else if (e.UserState.Equals(Results.SkyDriveDownload))
            {
                var resInfo = new StreamResourceInfo(e.Result, null);
                var reader = new StreamReader(resInfo.Stream);
                byte[] contents;
                using (BinaryReader bReader = new BinaryReader(reader.BaseStream))
                {
                    contents = bReader.ReadBytes((int)reader.BaseStream.Length);
                }
                string fileName = currLocalDir == "" ? currSkyDriveItem.Name : Path.Combine(currLocalDir,currSkyDriveItem.Name);
                IsolatedStorageFileStream stream = isoStore.CreateFile(fileName);
                stream.Write(contents, 0, contents.Length);
                stream.Close();
                DownloadSkyDriveItemComplete();
            }
            else if (e.UserState.Equals(Results.SkyDriveDelete))
            {
                DeleteSkyDriveItemComplete();
            }
        }
        private void OnClientUploadStringComplete(object sender, UploadStringCompletedEventArgs e)
        {
           // DataContractJsonSerializer deserializer;
            if (e.UserState.Equals(Results.SkyDriveDelete))
            {
                DeleteSkyDriveItemComplete();
            }
        }
        private void OnClientOpenWriteComplete(object sender, OpenWriteCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                GetSkyDriveItem(currSkyDriveDir);
            }
            else
            {
                MessageBox.Show("Error uploading file: " + e.Error.ToString());
            }
           
        }
        #region Helper method
        /// <summary>
        /// Build the API service URI.
        /// </summary>
        /// <param name="path">The relative path requested.</param>
        /// <returns>The request URI.</returns>
        private Uri BuildApiUri(string path,Results action)
        {
            UriBuilder builder = new UriBuilder(MainPage.ApiServiceUri);
            if (action == Results.SkyDriveDownload)
            {
                builder.Path += path+"/content";
                builder.Query = "download=true&access_token=" + HttpUtility.UrlEncode(this.skyDriveAccessToken);
            }
            else if (action == Results.SkyDriveUpload)
            {
                builder.Path += currSkyDriveDir+"/"+path;
                builder.Query = "access_token=" + HttpUtility.UrlEncode(this.skyDriveAccessToken);
            }
            else if(action == Results.SkyDriveDelete)
            {
                builder.Path += path;
                builder.Query = "access_token=" + HttpUtility.UrlEncode(this.skyDriveAccessToken);
            }
            else if(action == Results.UserInfo)
            {
                builder.Path += path;
                builder.Query = "access_token=" + HttpUtility.UrlEncode(this.skyDriveAccessToken);
            }else 
            {
                builder.Path += string.Format(skydriveFormat, path);
                builder.Query = "access_token=" + HttpUtility.UrlEncode(this.skyDriveAccessToken);
            }
            return builder.Uri;
        }

        /// <summary>
        /// Build the OAuth URI.
        /// </summary>
        /// <param name="scopes">The requested scopes.</param>
        /// <returns>The OAuth URI.</returns>
        private Uri BuildOAuthUri(string[] scopes)
        {
            List<string> paramList = new List<string>();
            paramList.Add("client_id=" + HttpUtility.UrlEncode(MainPage.ClientId));
            paramList.Add("scope=" + HttpUtility.UrlEncode(String.Join(" ", scopes)));
            paramList.Add("response_type=" + HttpUtility.UrlEncode("token"));
            paramList.Add("display=" + HttpUtility.UrlEncode("touch"));
            paramList.Add("redirect_uri=" + HttpUtility.UrlEncode(MainPage.RedirectUri));

            UriBuilder authorizeUri = new UriBuilder(MainPage.OAuthAuthorizeUri);
            authorizeUri.Query = String.Join("&", paramList.ToArray());
            return authorizeUri.Uri;
        }

        /// <summary>
        /// Process the URI fragment string.
        /// </summary>
        /// <param name="fragment">The URI fragment.</param>
        /// <returns>The key-value pairs.</returns>
        private Dictionary<string, string> ProcessFragments(string fragment)
        {
            Dictionary<string, string> processedFragments = new Dictionary<string, string>();

            if (fragment[0] == '#')
            {
                fragment = fragment.Substring(1);
            }

            string[] fragmentParams = fragment.Split('&');

            foreach (string fragmentParam in fragmentParams)
            {
                string[] keyValue = fragmentParam.Split('=');

                if (keyValue.Length == 2)
                {
                    processedFragments.Add(keyValue[0], HttpUtility.UrlDecode(keyValue[1]));
                }
            }

            return processedFragments;
        }
        #endregion
        #region Signin on authorization

        /// <summary>
        /// Handles the click event of the sign in button.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event data.</param>
        private void btnSkyDrive_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(skyDriveAccessToken) ||listSkyDriveItem ==null|| listSkyDriveItem.Count ==0) //login to access into skydrive
            {
                this.LaunchOAuthFlow();
            }
            else
            {
                DisplaySkyDriveItem(currSkyDriveDir, listSkyDriveItem, listFile);
                this.btnLocal.Visibility = Visibility.Visible;
                this.btnSkyDrive.Visibility = Visibility.Collapsed;
                currentDrive = CurrentDrive.SkyDrive;
            }
        }

        /// <summary>
        /// Handles the navigating event of the OAuth web browser control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event data.</param>
        private void OnAuthorizationBrowserNavigated(object sender, NavigationEventArgs e)
        {
            this.authorizationBrowser.Navigated -= this.OnAuthorizationBrowserNavigated;
            this.loadingGrid.Visibility = Visibility.Collapsed;
            this.authorizationBrowser.Visibility = Visibility.Visible;
        }

        /// <summary>
        /// Handles the navigating event of the OAuth web browser control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event data.</param>
        private void OnAuthorizationBrowserNavigating(object sender, NavigatingEventArgs e)
        {
            Uri uri = e.Uri;

            if (uri != null && uri.AbsoluteUri.StartsWith(MainPage.RedirectUri))
            {
                Dictionary<string, string> fragments = this.ProcessFragments(uri.Fragment);

                bool success = fragments.TryGetValue("access_token", out this.skyDriveAccessToken);

                e.Cancel = true;
                this.CompleteOAuthFlow(success);
            }
        }
        private void LaunchOAuthFlow()
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            this.authorizationBrowser.Navigating += this.OnAuthorizationBrowserNavigating;
            this.authorizationBrowser.Navigated += this.OnAuthorizationBrowserNavigated;
            this.authorizationBrowser.Navigate(this.BuildOAuthUri(this.scopes));
        }
        private void CompleteOAuthFlow(bool success)
        {
            this.authorizationBrowser.Navigated -= this.OnAuthorizationBrowserNavigated;
            this.authorizationBrowser.Navigating -= this.OnAuthorizationBrowserNavigating;

            this.authorizationBrowser.NavigateToString(String.Empty);
            this.authorizationBrowser.Visibility = Visibility.Collapsed;

            if (success)
            {
                this.GetSkyDriveUserData();
                this.btnSkyDrive.Visibility = Visibility.Collapsed;
            }
        }
        #endregion
        #endregion
        #region Get Local Item
        // Method to retrieve all directories, recursively, within a store. 
        public void GetPattern(string pattern, IsolatedStorageFile isoStorage)
        {
            GetAllLocalDirectories(pattern, isoStorage);
            GetAllLocalFiles(pattern, isoStorage);
        }
        public void GetAllLocalDirectories(string pattern, IsolatedStorageFile isoStorage)
        {
            string folderString = Path.GetDirectoryName(pattern);
            // Retrieve directories.
            List<String> directoryList = new List<String>(isoStorage.GetDirectoryNames(pattern));
            foreach (string s in directoryList)
            {
                bool found = false;
                for (int i = 0;(!found)&&i<listLocalItem.Count;i++)
                {
                    if (listLocalItem[i].Id == Path.Combine(folderString,s)) found = true;
                }
                if (!found)
                {
                    ItemStructure item = new ItemStructure();
                    item.Name = s;
                    item.Image = "Image/doc-icon.png";
                    item.Type = ItemType.Folder;
                    item.ParentID = folderString;
                    item.Id = Path.Combine(folderString, s);
                    listLocalItem.Add(item);
                }
            }
        }
        public void GetAllLocalFiles(string pattern, IsolatedStorageFile isoStorage)
        {
            // Get the root and file portions of the search string. 
             string folderString = Path.GetDirectoryName(pattern);
              
            List<String> fileList = new List<String>(isoStorage.GetFileNames(pattern));
            foreach (string s in fileList)
            {
                bool found = false;
                for (int i = 0;(!found)&&i<listLocalItem.Count;i++)
                {
                    if(listLocalItem[i].Id == s)found = true;
                }
                if (!found)
                {
                    ItemStructure item = new ItemStructure();
                    item.Name = s;
                    item.Type = ItemType.File;
                    item.Id = folderString == ""?s:Path.Combine(folderString,s);
                    item.ParentID = folderString;
                    listLocalItem.Add(item);
                }
            }
          
        }
        public void InitLocalItem()
        {
            isoStore = IsolatedStorageFile.GetUserStoreForApplication();
            listLocalItem = new List<ItemStructure>();
            GetLocalItem("*", isoStore);
        }
        public void GetLocalItem(string pattern, IsolatedStorageFile isoStorage)
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            GetPattern(pattern, isoStorage);
            GetLocalItemComplete(pattern);
        }
        public void GetLocalItemComplete(string pattern)
        {
            SaveItem(localFileName, isoStore, listLocalItem);
            DisplayLocalItem(pattern, listLocalItem, listFile);
            this.loadingGrid.Visibility = Visibility.Collapsed;
            this.txtTitle.Text = string.Format(titleProgram, "Local");
            this.btnSkyDrive.Visibility = Visibility.Visible;
            this.btnLocal.Visibility = Visibility.Collapsed;
            currentDrive = CurrentDrive.Local;
        }
        private void DisplayLocalItem(string pattern, List<ItemStructure> listLocal, ListBox listView)
        {
            string folderString = Path.GetDirectoryName(pattern);
            List<ItemStructure> listItem = new List<ItemStructure>();
            foreach (var o in listLocal)
            {
                if (o.ParentID == folderString) listItem.Add(o);
            }
            // Get the root of the search string. 
            if (folderString != "")
            {
                // find last occurence of slash character and cut the string
                //get parent folder
                string parentFolder = string.Empty;
                int pos = folderString.LastIndexOf("\\");
                if (pos == -1)
                {
                    parentFolder = "";
                }
                else
                {
                    parentFolder = folderString.Substring(0, pos);
                }
                ItemStructure item = new ItemStructure();
                item.Name = "..";
                item.ParentID = pattern;
                item.Id = parentFolder;
                item.Type = ItemType.Up;
                listItem.Insert(0, item);
            }
            listView.ItemsSource = listItem;
        }
        public void DeleteLocalItem(ItemStructure item, IsolatedStorageFile isoStorage)
        {
            if (isoStorage.FileExists(item.Id))
            {
                isoStorage.DeleteFile(item.Id);
            }
            DeleteLocalItemComplete(item, listLocalItem,isoStore);
        }
        public void DeleteLocalItemComplete(ItemStructure item, List<ItemStructure> listItem, IsolatedStorageFile isoStorage )
        {
            listItem.Remove(item);
            GetLocalItem(item.ParentID,isoStorage);
        }
        #endregion
        #region App Event
        public MainPage()
        {
            this.InitializeComponent();
        }
        protected override void OnBackKeyPress(CancelEventArgs e)
        {
            if (this.authorizationBrowser.Visibility == Visibility.Visible)
            {
                this.CompleteOAuthFlow(false);
                e.Cancel = true;
            }
            else
            {
                base.OnBackKeyPress(e);
            }
        }
        private void btnLocal_Click(object sender, RoutedEventArgs e)
        {
            this.loadingGrid.Visibility = Visibility.Visible;
            InitLocalItem();
            this.btnLocal.Visibility = Visibility.Collapsed;
            this.btnSkyDrive.Visibility = Visibility.Visible;
            this.loadingGrid.Visibility = Visibility.Collapsed;
        }
        private void ApplicationBarIconButton_Click(object sender, EventArgs e)
        {
            ApplicationBarIconButton btn = sender as ApplicationBarIconButton;
            switch (btn.Text.ToLower())
            {
                case "upload":
                    if (currSkyDriveItem != null )
                    {
                        if (currLocalItem == null || currLocalItem.Type != ItemType.File)
                        {
                            MessageBox.Show("Please select a local file");
                        }
                        else
                        {
                            UploadSkyDriveItem();
                        }
                    }
                    else
                    {
                        MessageBox.Show("Please select a skydrive folder");
                    }
                    break;
                case "download":
                    if (currSkyDriveItem != null && currSkyDriveItem.Type != ItemType.File)
                    {
                        MessageBox.Show("Please select a skydrive file");
                    }
                    else
                    {
                        DownloadSkyDriveItem();
                    }
                    break;
                case "delete":
                    if (currentDrive == CurrentDrive.SkyDrive)
                    {
                        if (currSkyDriveItem == null)
                        {
                            MessageBox.Show("Please select a skydrive item");
                        }
                        else
                        {
                            DeleteSkyDriveItem();
                        }
                    }
                    else if (currentDrive == CurrentDrive.Local)
                    {
                        if (currLocalItem == null)
                        {
                            MessageBox.Show("Please select a local item");
                        }
                        else
                        {
                            DeleteLocalItem(currLocalItem, isoStore);
                        }
                    }
                    break;
                case "sync":
                    if (currentDrive == CurrentDrive.Local)
                    {
                        SaveItem("AppSetting/LocalItemStructures.xml", isoStore, listLocalItem);
                    }
                    else if(currentDrive == CurrentDrive.SkyDrive)
                    {
                        SaveItem("AppSetting/SkyDirveItemStructures.xml", isoStore, listSkyDriveItem);
                    }
                    
                    
                    break;
            }
        }
        private void OnPhotoChooserTaskCompleted(object sender, PhotoResult e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("Error choosing photo: " + e.Error.ToString());
            }
            else
            {
                WebClient client = new WebClient();
                string[] filePathSegments = e.OriginalFileName.Split('\\');
                string fileName = filePathSegments[filePathSegments.Length - 1];
                client.OpenWriteCompleted
                    += OnPhotoChooserTaskCompleted_UploadCompleted;
                //client.OpenWriteAsync("me/skydrive", fileName, e.ChosenPhoto);
            }
        }
        private void OnPhotoChooserTaskCompleted_UploadCompleted(object sender, System.Net.OpenWriteCompletedEventArgs args)
        {
            if (args.Error == null)
            {
                IDictionary<string, object> file = (IDictionary<string, object>)args.Result;
                MessageBox.Show("File uploaded. Link: " + file["source"]);
            }
            else
            {
                MessageBox.Show("Error uploading file: " + args.Error.ToString());
            }
        }
        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            
            // This part of the code sets up a few directories and files in the 
            // store.
            //
            isoStore = IsolatedStorageFile.GetUserStoreForApplication();
            //create a folder contain App file system
            isoStore.CreateDirectory("AppSetting");

            // Create directory
            isoStore.CreateDirectory("TopLevelDirectory");
            isoStore.CreateDirectory("TopLevelDirectory/SecondLevel");
            isoStore.CreateDirectory("TopLevelDirectory/SecondLevel/ThirdLevel");
            isoStore.CreateDirectory("TopLevelDirectory/SecondLevel/ThirdLevel/FourthLevel");
            isoStore.CreateDirectory("TopLevelDirectory/SecondLevel/ThirdLevel/Four1");
            isoStore.CreateDirectory("TopLevelDirectory/SecondLevel/ThirdLevel/Four2");
            isoStore.CreateDirectory("AnotherTopLevelDirectory/InsideDirectory");
            isoStore.CreateFile("InTheRoot.txt");
            isoStore.CreateFile("AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt");
            

            //Init all variable
            this.btnLocal.Visibility = Visibility.Collapsed;
            this.btnSkyDrive.Visibility = Visibility.Visible;
            this.currSkyDriveDir = rootSkyDrive; //string.Format(skydriveFormat, rootSkyDrive);
            this.parentCurrSkyDriveDir = this.currSkyDriveDir;
            this.listLocalItem = new List<ItemStructure>();
            this.listSkyDriveItem = new List<ItemStructure>();
            // Start with Local file
            this.InitLocalItem();
        }
        private void listFile_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var listBox = sender as ListBox;
            if (listBox != null)
            {

                //Item selected
                ItemStructure currItem = (ItemStructure)listFile.SelectedItem;
                if (currItem != null)
                {
                    if (currentDrive == CurrentDrive.Local)
                    {
                        currLocalItem = currItem;
                        // check if file return
                        if (currLocalItem.Type == ItemType.File)
                        {
                            return;
                        }
                        // check if Up
                        if (currLocalItem.Type == ItemType.Up)
                        {
                            // find last occurence of slash character and cut the string
                            int pos = currLocalDir.LastIndexOf("\\");
                            if (pos == -1)
                            {
                                currLocalDir = "";
                            }
                            else
                            {
                                currLocalDir = currLocalDir.Substring(0, pos);
                            }
                            //get parent folder
                            GetLocalItem(Path.Combine(currLocalItem.Id, "*"), isoStore);

                        }
                        else

                            // check if folder
                            if (currLocalItem.Type == ItemType.Folder)
                            {
                                currLocalDir = Path.Combine(currLocalDir, currLocalItem.Name);
                                GetLocalItem(Path.Combine(currLocalItem.Id, "*"), isoStore);
                            }
                    }
                    else if (currentDrive == CurrentDrive.SkyDrive)
                    {
                        currSkyDriveItem = currItem;
                        // check if file return
                        if (currSkyDriveItem.Type == ItemType.File)
                        {
                            return;
                        }
                        if (currSkyDriveItem.Type == ItemType.Up)
                        {
                            bool found = false;
                            // select parent folder
                            for(int i = 0;!found&&i<listSkyDriveItem.Count;i++)
                            {
                              if(listSkyDriveItem[i].Id==currSkyDriveItem.Id)
                              {
                                  found = true;
                                  currSkyDriveItem = listSkyDriveItem[i];
                              }
                            }
                            if (!found)
                            {
                                this.parentCurrSkyDriveDir = rootSkyDrive;
                                this.currSkyDriveDir = rootSkyDrive;
                            }
                            else
                            {
                                this.parentCurrSkyDriveDir = currSkyDriveItem.ParentID;
                                this.currSkyDriveDir = currSkyDriveItem.Id;
                            }
                        }
                        else if (currSkyDriveItem.Type == ItemType.Folder || currSkyDriveItem.Type == ItemType.Album)
                        {
                            this.parentCurrSkyDriveDir = currSkyDriveItem.ParentID;
                            this.currSkyDriveDir = currSkyDriveItem.Id;
                        }
                        DisplaySkyDriveItem(this.currSkyDriveDir,this.listSkyDriveItem,this.listFile);
                    }
                }
            }
        } // End of GetFiles.
        #endregion
    }
}